package com.kotlinvben.handler

import com.kotlinvben.bean.Result
import com.kotlinvben.exception.BusinessErrorCode
import com.kotlinvben.exception.BusinessException
import jakarta.validation.ConstraintViolationException
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.validation.BindException
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestControllerAdvice

@RestControllerAdvice
class GlobalExceptionHandler {
    private val log = LoggerFactory.getLogger(GlobalExceptionHandler::class.java)

    @ExceptionHandler(BusinessException::class)
    fun handleBusinessException(e: BusinessException): Result<Nothing> {
        log.warn("业务异常: {}", e.message, e)
        return Result.error(e.code, e.message)
    }

    @ExceptionHandler(MethodArgumentNotValidException::class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handleValidationException(e: MethodArgumentNotValidException): Result<Nothing> {
        val message = e.bindingResult.fieldErrors.joinToString(", ") { 
            "${it.field}: ${it.defaultMessage}" 
        }
        log.warn("参数校验异常: {}", message, e)
        return Result.error(BusinessErrorCode.BAD_REQUEST, message)
    }

    @ExceptionHandler(BindException::class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handleBindException(e: BindException): Result<Nothing> {
        val message = e.bindingResult.fieldErrors.joinToString(", ") { 
            "${it.field}: ${it.defaultMessage}" 
        }
        log.warn("参数绑定异常: {}", message, e)
        return Result.error(BusinessErrorCode.BAD_REQUEST, message)
    }

    @ExceptionHandler(ConstraintViolationException::class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handleConstraintViolationException(e: ConstraintViolationException): Result<Nothing> {
        val message = e.constraintViolations.joinToString(", ") { 
            "${it.propertyPath}: ${it.message}" 
        }
        log.warn("约束违反异常: {}", message, e)
        return Result.error(BusinessErrorCode.BAD_REQUEST, message)
    }

    @ExceptionHandler(Exception::class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    fun handleException(e: Exception): Result<Nothing> {
        log.error("未处理的异常", e)
        return Result.error(
            BusinessErrorCode.INTERNAL_ERROR,
            "服务器内部错误: ${e.message}"
        )
    }
} 